package org.grow.erp.controller;

import com.querydsl.core.BooleanBuilder;
import com.querydsl.core.QueryResults;
import com.querydsl.jpa.impl.JPAQueryFactory;
import org.grow.common.dto.PagedResults;
import org.grow.common.exception.ElMessageException;
import org.grow.common.exception.ElNoticeException;
import org.grow.common.exception.OperationProcessException;
import org.grow.erp.dao.OutStockBillRepository;
import org.grow.erp.entity.*;
import org.grow.support.service.CodeGene;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.security.core.context.SecurityContextHolder;
import org.springframework.util.CollectionUtils;
import org.springframework.util.StringUtils;
import org.springframework.web.bind.annotation.*;

import java.math.BigDecimal;
import java.time.LocalDateTime;
import java.util.List;
import java.util.Optional;

/**
 * @Author: xwg
 * @CreateDate: 2022/1/19
 */
@RequestMapping("/erp/outStock")
@RestController
public class OutStockController {
    @Autowired
    private OutStockBillRepository outStockBillRepository;
    @Autowired
    private ThreadLocal<CodeGene> codeGeneThreadLocal;

    @PostMapping("/insert")
    public OutStockBill insert(@RequestBody OutStockBill outStockBill) {
        outStockBill.setOutStockCode(codeGeneThreadLocal.get().nextCode("OS"));
        outStockBill.setAbandoned(false);
        outStockBill.setVersion(0);


//        初次新增单据 的暂存
        outStockBill.setBillOperator(
                SecurityContextHolder.getContext().getAuthentication().getName());
        outStockBill.setOperateState(OperateState.notSubmit);
        outStockBill.setBillAuditor(null);
        outStockBill.setAuditState(AuditState.NA);


//        行内小计和 单据总计 如果完全信赖前端 可以省略
        outStockBill.refreshComputedFields();

        /*构建完整模型 也可以做成接口*/
  /*      List<OutStockMaterialDetail> details = outStockBill.getOutStockMaterialDetails();
        details.forEach(x -> {
            x.getOutStockMaterialDetailId().setOutStockFk(outStockBill.getOutStockCode());
            x.setOutStockBill(outStockBill);
        });*/
        outStockBill.refreshDomainRelationship();

        OutStockBill save = outStockBillRepository.save(outStockBill);

        return save;

    }

    @GetMapping("/find/{code}")
    public Optional<OutStockBill> find(@PathVariable("code") String code) {
        Optional<OutStockBill> byId = outStockBillRepository.findById(code);
        return byId;
    }

    @PutMapping("/modify")
    public OutStockBill modify(@RequestBody OutStockBill outStockBill) {
        Optional<OutStockBill> byId = outStockBillRepository.findById(outStockBill.getOutStockCode());
        if (!byId.isPresent()) {
            throw new ElMessageException("不存在本领域对象，建议去新增");
        }
        outStockBill.setAbandoned(false);
        if (outStockBill.getOperateState() != OperateState.notSubmit) {
            throw new ElNoticeException("流程不正确，只有处于未提交状态的单据才能修改");
        }
        outStockBill.setOperateState(OperateState.notSubmit);
        outStockBill.setAuditState(AuditState.NA);
        outStockBill.setBillAuditor(null);
        outStockBill.setBillOperator(SecurityContextHolder.getContext().getAuthentication().getName());

        outStockBill.refreshComputedFields();
        outStockBill.refreshDomainRelationship();

        OutStockBill save = this.outStockBillRepository.save(outStockBill);
        return save;

    }

    @Autowired
    private JPAQueryFactory jpaQueryFactory;

    QOutStockBill ob = QOutStockBill.outStockBill;


    @PostMapping("/query/apply")
    public PagedResults<OutStockBill> queryApply(@RequestBody OutStockApplyQC outStockApplyQC) {
        Integer pageNum = outStockApplyQC.getPageNum();
        Integer pageSize = outStockApplyQC.getPageSize();
        int pageStart = (pageNum - 1) * pageSize;
        OutStockApplyQC qc = outStockApplyQC;

        BooleanBuilder builder = new BooleanBuilder();
        /*静态部分与动态部分*/
        /**
         *     private String applierSml;
         *     private List<AuditState> auditStates;
         *     private List<OperateState> operateStates;
         * */
        builder.and(ob.billOperator.eq(SecurityContextHolder.getContext().getAuthentication().getName()));
        if (StringUtils.hasText(qc.getApplierSml())) {

            builder.and(ob.applier.like("%" + qc.getApplierSml() + "%"));
        }
        if (!CollectionUtils.isEmpty(qc.getAuditStates())) {

            builder.and(ob.auditState.in(qc.getAuditStates()));
        }
        if (!CollectionUtils.isEmpty(qc.getOperateStates())) {

            builder.and(ob.operateState.in(qc.getOperateStates()));
        }

        builder.and(ob.abandoned.eq(false));

        QueryResults<OutStockBill> re = jpaQueryFactory.selectFrom(ob)
                .where(builder)
                .orderBy(ob.outStockTime.desc())
                .offset(pageStart)
                .limit(pageSize).fetchResults();
        return new PagedResults<>(re.getTotal(), re.getResults());

    }

    @PostMapping("/query/audit")
    public PagedResults<OutStockBill> queryAudit(@RequestBody OutStockAuditQC qc) {
        Integer pageNum = qc.getPageNum();
        Integer pageSize = qc.getPageSize();
        int pageStart = (pageNum - 1) * pageSize;

        BooleanBuilder builder = new BooleanBuilder();
        /*
            /*能看到所有已经提交状态的单据*/
//        private String billOperatorSml;
//        private String applierSml;
//        * */
        builder.and(ob.operateState.in(OperateState.notAudit,OperateState.audited));

        if (StringUtils.hasText(qc.getBillOperatorSml())) {
            builder.and(ob.billOperator.like("%"+qc.getBillOperatorSml()+"%"));
        }

        if (!CollectionUtils.isEmpty(qc.getAuditStates())) {
            builder.and(ob.auditState.in(qc.getAuditStates()));
        }

        builder.and(ob.abandoned.eq(false));

        QueryResults<OutStockBill> results = jpaQueryFactory.selectFrom(ob)
                .where(builder)
                .orderBy(ob.outStockTime.desc())
                .offset(pageStart)
                .limit(pageSize).fetchResults();

        return new PagedResults<>(results.getTotal(),results.getResults());
    }

    @PutMapping("/submit/{code}")
    public Integer submit(@PathVariable("code") String code){
        Optional<OutStockBill> byId = outStockBillRepository.findById(code);
        boolean present = byId.isPresent();
        if (present){
            OutStockBill outStockBill = byId.get();

            if (outStockBill.getOperateState()!=OperateState.notSubmit){
                throw new OperationProcessException("权限拦截");
            }
            outStockBill.setOperateState(OperateState.notAudit);
            return 1;

        }else {
            return 0;
        }

    }

    @GetMapping("/test")
    public String test() {
        return SecurityContextHolder.getContext().getAuthentication().getName() + "  === " + LocalDateTime.now();
    }
}
